Passed
Push — master ( 55041a...8df89b )
by Night
52s
created

arrayFuncs.isFirst   A

Complexity

Conditions 1
Paths 2

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 2
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
/** global: UB */
2
/** global: Buffer */
3
4
/*! ARRAY UTILS */
5
6
var arrayFuncs = {
7
8
	merge: function(){
9
		var arr = this;
10
		var val1 = arr[0];
11
12
		// if array of strings
13
		if (val1.isString()){
14
			return val1.join("");
15
		}
16
17
		// if array of arrays
18
		if (val1.isArray()){
19
			var merged = [];
20
			for (var a = 0, al = arr.length; a<al; a++){
21
				merged.addArray(arr[a]);
22
			}
23
			return merged;
24
		}
25
26
		// if array of Buffers
27
		//removeIf(nodejs)
28
		if (val1 instanceof Buffer){
29
30
			// calc the total length of all buffers
31
			var buffers = arr;
32
			var len = 0;
33
			for(var b = 0, bl = buffers.length; b < bl; b++) {
34
				len += buffers[b].length;
35
			}
36
37
			// create a new buffer of that length
38
			var mega = new Buffer(len);
39
40
			// write all buffers into the mega buffer
41
			var cur = 0;
42
			for(var b = 0, bl = buffers.length; b < bl; b++) {
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable bl already seems to be declared on line 33. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
Comprehensibility Naming Best Practice introduced by
The variable b already seems to be declared on line 33. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
43
				buffers[b].copy(mega, cur, 0);
44
				cur += buffers[b].length;
45
			}
46
			return mega;
47
		}
48
		//endRemoveIf(nodejs)
49
50
		return null;
51
	},
52
	
53
	indexOf: function(value){
54
		var list = this;
55
		if (list.length === 0) {
56
			return -1;
57
		}
58
		for (var a = 0, al = list.length;a<al;a++){
59
			if (list[a] == value){
60
				return a;
61
			}
62
		}
63
		return -1;
64
	},
65 View Code Duplication
	lastIndexOf: function(value){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
66
		var list = this;
67
		if (list.length === 0) {
68
			return -1;
69
		}
70
		for (var a = list.length-1;a>=0;a--){
71
			if (list[a] == value){
72
				return a;
73
			}
74
		}
75
		return -1;
76
	},
77
	
78 View Code Duplication
	count: function(value, not = false){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
79
		var list = this;
80
		var total = 0;
81
		for (var a = 0, al = list.length;a<al;a++){
82
			if (not) {
83
				if (list[a] != value) {
84
					total++;
85
				}
86
			}else {
87
				if (list[a] == value) {
88
					total++;
89
				}
90
			}
91
		}
92
		return total;
93
	},
94
	or: function(list2){
95
		var list = this;
96
		if (Exists(list)) {
97
			return list;
98
		}
99
		return list2;
100
	},
101
	
102
	part: function(start, end){
103
		var list = this;
104
		
105
		// quickly exit if no items or no results possible
106
		if (list == null || list.length === 0 || start > end || start >= list.length) {
1 ignored issue
show
Best Practice introduced by
Comparing list to null using the == operator is not safe. Consider using === instead.
Loading history...
107
			return [];
108
		}
109
		
110
		// just get the part we need
111
		return list.slice(start, end + 1);
112
	},
113
	
114
	swap: function(slot1, slot2){
115
		var list = this;
116
		var temp = list[slot2];
117
		list[slot2] = list[slot1];
118
		list[slot1] = temp;
119
	},
120
121
	add: function(item){
122
		var list = this;
123
		list.push(item);
124
		return list.length - 1;
125
	},
126
	addToStart: function(item){
127
		var list = this;
128
		list.unshift(item);
129
		return 0;
130
	},
131
	/** return false if item exists, true if item does not */
132
	addOnce: function(value){
133
		var list = this;
134
		
135
		// return false if item exists
136
		if (list.indexOf(value) > -1) {
137
			return false;
138
		}
139
		
140
		// add if not found
141
		list.push(value);
142
		return true;
143
	},
144
	
145
	addArray: function(toAdd, addAtSlot = -1, modifyMain = true){
146
		var list = this;
147
		
148
		if (toAdd != null && toAdd.length > 0) {
1 ignored issue
show
Best Practice introduced by
Comparing toAdd to null using the != operator is not safe. Consider using !== instead.
Loading history...
149
			if (!modifyMain) {
150
				list = list.concat(); /// shallow clone
151
			}
152
			
153
			// set length first so allocates memory (maybe?)
154
			var origLen = list.length;
155
			if (addAtSlot === -1){
156
				list.length += toAdd.length;
157
			}
158
			
159
			// set all slots
160
			var next = addAtSlot === -1 ? origLen : addAtSlot;
161
			for (var a = 0, al = toAdd.length;a<al;a++, next++){
162
				list[next] = toAdd[a];
163
			}
164
		}
165
		return list;
166
	},
167
	
168
	/** adds the given value many times */
169
	addManyTimes: function(val, times){
170
		var list = this;
171
		
172
		if (times <= 0) {
173
			return list;
174
		}
175
		
176
		var n = list.length;
177
		for (var t = 0;t<times;t++){
178
			list[n++] = val;
179
		}
180
		
181
		return list;
182
	},
183
	
184
	addRange: function(toAdd, startSlot, endSlot){
185
		var list = this;
186
		
187
		// exit if no work
188
		if (endSlot < startSlot) {
189
			return;
190
		}
191
		
192
		// per wanted slot of the `add` array
193
		startSlot = startSlot.limitToArray(toAdd);
194
		endSlot = endSlot.limitToArray(toAdd);
195
		for (var s = startSlot;s <= endSlot;s++){
196
			
197
			// add into `main` array
198
			list.push(toAdd[s]);
199
			
200
		}
201
	},
202
	
203
	/** returns final index of added item, or index of already existing item */
204
	findOrAdd: function(value){
205
		var list = this;
206
		
207
		// return index of item if exists
208
		var i = list.indexOf(value);
209
		if (i > -1) {
210
			return i;
211
		}
212
		
213
		// add if not found
214
		i = list.length;
215
		list[i] = value;
216
		return i;
217
	},
218
	
219
	insertOne: function(item, slot){
220
		var list = this;
221
		
222
		// adds one slot at the given point
223
		// modifies the main array
224
		
225
		list.splice(slot, 0, item);
226
	},
227
228
	/** if slot = -1 or outside the array, the item is added to the END of the array.
229
	 * Otherwise the item is added at the given slot. */
230
	insertOneOrAdd: function(item, slot){
231
		var list = this;
232
		
233
		// adds one slot at the given point
234
		// modifies the main array
235
		
236
		if (slot < 0 || slot >= list.length) {
237
			list.push(item);
238
			return list.length - 1;
239
		}
240
		list.splice(slot, 0, item);
241
		return slot;
242
	},
243
	insertArray: function(newItems, slot, returnNew = true){
244
		var list = this;
245
		
246
		// adds many slots at the given point
247
		// returns a new array
248
		if(returnNew){
249
			return list.slice(0, slot).concat(newItems).concat(list.slice(slot));
250
		}
251
		
252
		// adds many slots at the given point
253
		// modifies the main array
254
		for (var a = 0, al = newItems.length;a<al;a++){
255
			list.splice(slot++, 0, newItems[a]);
256
		}
257
		return list;
258
	},
259
	insertArrayAfter: function(newItems, after){
260
		var list = this;
261
		if (list.isLast(after)) {
262
			list.addArray(newItems);
263
		} else {
264
			var i = list.indexOf(after);
265
			list.insertArray(i + 1, newItems);
266
		}
267
	},
268
	
269
270
	removeAndInsert: function(from, to){
271
		var list = this;
272
		
273
		// ensure slots within array
274
		var al = list.length;
275
		from = from.limitTo(0, al - 1);
276
		to = to.limitTo(0, al - 1);
277
		if (to < from) {
278
			var i1 = to;
279
			var i2 = from;
280
		}else {
281
			i1 = from;
282
			i2 = to;
283
		}
284
		
285
		// fill unaffected header
286
		var result = [];
287
		if(i1 > 0){
288
			for (var a = 0;a<i1;a++){
289
				result[a] = list[a];
290
			}
291
		}
292
		
293
		// fill "to"
294
		result[to] = list[from];
295
		
296
		// fill between from and to
297
		if(to < from){
298
			for (a = to + 1; a <= from; a++) {
299
				result[a] = list[a - 1];
300
			}
301
		}else {
302
			for (a = from; a < to; a++) {
303
				result[a] = list[a + 1];
304
			}
305
		}
306
		
307
		// fill unaffected footer
308
		for (var a = i2 + 1;a<al;a++){
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable a already seems to be declared on line 288. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
309
			result[a] = list[a];
310
		}
311
		
312
		return result;
313
	},
314
	
315
	/** replace a range of items with a given array */
316
	replaceRange: function(replaceStartSlot, replaceEndSlot, newItems, returnNew = true){
317
		var list = this;
318
		
319
		
320
		// simply remove a single item
321
		if (replaceStartSlot == replaceEndSlot && newItems.length === 0) {
322
			if (returnNew) {
323
				list = list.concat();
324
			}
325
			list.splice(replaceStartSlot, 1);
326
			return list;
327
			
328
		// simply replace a single item
329
		}else if (replaceStartSlot == replaceEndSlot && newItems.length === 1) {
330
			if (returnNew) {
331
				list = list.concat();
332
			}
333
			list[replaceStartSlot] = newItems[0];
334
			return list;
335
			
336
		}
337
		
338
		// alt method if returning a new array
339
		if(returnNew){
340
			return list.slice(0, replaceStartSlot).concat(newItems).concat(list.slice(replaceEndSlot + 1));
341
		}
342
		
343
		// remove many
344
		list.splice(replaceStartSlot, (replaceEndSlot - replaceStartSlot) + 1);
345
		
346
		// insert many
347
		var slot = replaceStartSlot;
348
		for (var a = 0, al = newItems.length;a<al;a++){
349
			list.splice(slot++, 0, newItems[a]);
350
		}
351
		return list;
352
	},
353
	
354
	replace: function(find, replace, stringReplace = false){
355
		var list = this;
356
		for (var i = 0, il = list.length;i<il;i++){
357
			if (stringReplace){
358
359
				// replace substring within string items
360
				var str = list[i];
361
				if (str && str.constructor === String) {
362
					list[i] = str.replaceAll(find, replace);
363
				}
364
			}else{
365
366
				// replace entire items
367
				if (list[i] == find) {
368
					list[i] = replace;
369
				}
370
			}
371
		}
372
	},
373
	replaceOnce: function(find, replace){
374
		var list = this;
375
		for (var i = 0, il = list.length;i<il;i++){
376
			if (list[i] == find) {
377
				list[i] = replace;
378
				return;
379
			}
380
		}
381
	},
382
	replaceMany: function(findArray, replaceArray){
383
		var list = this;
384
		if (findArray.length != replaceArray.length){
385
			return;
386
		}
387
		for (var i = 0, il = list.length;i<il;i++){
388
			for (var f = 0, fl = findArray.length;f<fl;f++){
389
				var find = findArray[f];
390
				if (list[i] == find) {
391
					list[i] = replaceArray[f];
392
					break;
393
				}
394
			}
395
		}
396
	},
397
	
398
	
399
	remove: function(value, stringReplace = false){
400
		var list = this;
401
		for (var i = 0, il = list.length;i<il;i++){
402
			if (stringReplace){
403
404
				// remove substring within string items
405
				var str = list[i];
406
				if (str && str.constructor === String) {
407
					list[i] = str.removeAll(value);
408
				}
409
			}else{
410
411
				// remove entire items
412
				if (list[i] == value) {
413
					list.splice(i, 1);
414
					i--;
1 ignored issue
show
Complexity Coding Style introduced by
You seem to be assigning a new value to the loop variable i here. Please check if this was indeed your intention. Even if it was, consider using another kind of loop instead.
Loading history...
415
					il--;
416
				}
417
			}
418
		}
419
	},
420
	removeOnce: function(val){
421
		var list = this;
422
		var i = list.indexOf(val);
423
		if (i > -1) {
424
			list.splice(i, 1);
425
		}
426
		return i;
427
	},
428
	removeFirst: function(returnNew = false){
429
		var list = this;
430
431
		// return new
432
		if (returnNew) {
433
			return list.slice(1);
434
		}
435
436
		// modify existing
437
		if (list.length > 0) {
438
			list.splice(0, 1);
439
		}
440
		return list;
441
	},
442
	removeFirstX: function(count, returnNew = false){
443
		var list = this;
444
		
445
		// if fewer items than wanted, clear entire array
446
		if (list.length < count) {
447
			if (returnNew) {
448
				return [];
449
			}
450
			list.length = 0;
451
			return list;
452
		}
453
		
454
		// delete X items from start
455
		// return new
456
		if (returnNew) {
457
			return list.slice(count);
458
		}
459
460
		// modify existing
461
		list.splice(0, count);
462
		return list;
463
	},
464
	removeLast: function(returnNew = false){
465
		var list = this;
466
467
		// return new
468
		if (returnNew) {
469
			return list.slice(0, list.length - 1);
470
		}
471
472
		// modify existing
473
		if (list.length > 0) {
474
			list.splice( - 1, 1);
475
		}
476
		return list;
477
	},
478
	removeLastX: function(count, returnNew = false){
479
		var list = this;
480
		
481
		// if fewer items than wanted, clear entire array
482
		if (list.length < count) {
483
			if (returnNew) {
484
				return [];
485
			}
486
			list.length = 0;
487
			return list;
488
		}
489
		
490
		// delete X items from end
491
		// return new
492
		if (returnNew) {
493
			return list.slice(0, list.length - count);
494
		}
495
		
496
		// modify existing
497
		list.splice( -count, count);
498
		return list;
499
	},
500
	
501
	removeEdges: function(fromLeftEdge, fromRightEdge){
502
		var list = this;
503
		if ((list.length - fromLeftEdge - fromRightEdge) <= 0) {
504
			return [];
505
		}
506
		return list.slice(fromLeftEdge, list.length - fromRightEdge);
507
	},
508
	
509
	
510
	splitAt: function(slot, includeSlot = false, includeInFirst = false){
511
		var list = this;
512
		if (includeSlot) {
513
			if (includeInFirst) {
514
				return [list.slice(0, slot + 1), list.slice(slot + 1)];
515
			}else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
516
				return [list.slice(0, slot), list.slice(slot)];
517
			}
518
		}
519
		return [list.slice(0, slot), list.slice(slot+1)];
520
	},
521
	splitAtEvery: function(val){
522
		var list = this;
523
		var splits = [];
524
		var lastSlot = 0;
525
		for (var a = 0, al = list.length;a<al;a++){
526
			if (list[a] == val && a > lastSlot) {
527
				splits.push(list.slice(lastSlot, a));
528
				lastSlot = a + 1;
529
			}
530
		}
531
		return splits;
532
	},
533
	
534
	moveToTop: function(slot, returnNew = false){
535
		var list = this;
536
537 View Code Duplication
		if (returnNew){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
538
539
			// ALWAYS RETURNS NEW ARRAY
540
			
541
			// exit quickly if slot not in array
542
			var al = list.length;
543
			if (slot < 0 || slot >= al) {
544
				return list.concat();
545
			}
546
			
547
			// create new array with slot on top
548
			var newArr = [list[slot]];
549
			var n = 1;
550
			
551
			// add all other slots
552
			for (var a = 0;a<al;a++){
553
				if (a != slot) {
554
					newArr[n++] = list[a];
555
				}
556
			}
557
558
			return newArr;
559
		}
560
561
562
		// MODIFIES ARRAY IN PLACE
563
		
564
		// exit quickly if slot not in array
565
		var al = list.length;
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable al already seems to be declared on line 542. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
566
		if (slot < 0 || slot >= al) {
567
			return;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Are you sure this return statement is not missing an argument? If this is intended, consider adding an explicit undefined like return undefined;.
Loading history...
568
		}
569
		
570
		// delete and re-add slot
571
		var val = list[slot];
572
		list.splice(slot, 1);
573
		list.unshift(val);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
574
	},
575
	moveToBottom: function(slot, returnNew = false){
576
		var list = this;
577
578 View Code Duplication
		if (returnNew){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
579
580
			// ALWAYS RETURNS NEW ARRAY
581
			
582
			// exit quickly if slot not in array
583
			var al = list.length;
584
			if (slot < 0 || slot >= al) {
585
				return list.concat();
586
			}
587
			
588
			// create new array with slot on top
589
			var newArr = [];
590
			var n = 0;
591
			
592
			// add all other slots
593
			for (var a = 0;a<al;a++){
594
				if (a != slot) {
595
					newArr[n++] = list[a];
596
				}
597
			}
598
			
599
			// add slot to bottom
600
			newArr[n++] = list[slot];
0 ignored issues
show
Unused Code introduced by
The assignment to variable n seems to be never used. Consider removing it.
Loading history...
601
			return newArr;
602
603
		}
604
605
		// MODIFIES ARRAY IN PLACE
606
		
607
		// exit quickly if slot not in array
608
		var al = list.length;
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable al already seems to be declared on line 583. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
609
		if (slot < 0 || slot >= al) {
610
			return;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Are you sure this return statement is not missing an argument? If this is intended, consider adding an explicit undefined like return undefined;.
Loading history...
611
		}
612
		
613
		// delete and re-add slot
614
		var val = list[slot];
615
		list.splice(slot, 1);
616
		list.push(val);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
617
	},
618
	moveUp: function(item){
619
		var list = this;
620
		
621
		// MODIFIES ARRAY IN PLACE
622
		
623
		// exit quickly if slot not in array, or already on top
624
		var slot = list.indexOf(item);
625
		if (slot <= 0) {
626
			return false;
627
		}
628
		
629
		// move one up
630
		list.swap(slot, slot - 1);
631
		return true;
632
	},
633
	moveDown: function(item){
634
		var list = this;
635
		
636
		// MODIFIES ARRAY IN PLACE
637
		
638
		// exit quickly if slot not in array, or already at bottom
639
		var al = list.length;
640
		var slot = list.indexOf(item);
641
		if (slot < 0 || slot >= (al - 1)) {
642
			return false;
643
		}
644
		
645
		// move one down
646
		list.swap(slot, slot + 1);
647
		return true;
648
	},
649
	moveSlotUp: function(slot){
650
		var list = this;
651
		
652
		// MODIFIES ARRAY IN PLACE
653
		
654
		// exit quickly if slot not in array, or already on top
655
		var al = list.length;
656
		if (slot <= 0 || slot >= al) {
657
			return false;
658
		}
659
		
660
		// move one up
661
		list.swap(slot, slot - 1);
662
		return true;
663
	},
664
	moveSlotDown: function(slot){
665
		var list = this;
666
		
667
		// MODIFIES ARRAY IN PLACE
668
		
669
		// exit quickly if slot not in array, or already at bottom
670
		var al = list.length;
671
		if (slot < 0 || slot >= (al - 1)) {
672
			return false;
673
		}
674
		
675
		// move one down
676
		list.swap(slot, slot + 1);
677
		return true;
678
	},
679
	/** Move an item from the given list, to the start/end of the target list */
680
	moveToArray: function(item, toList, evenIfExists = false, addToEnd = true){
681
		var list = this;
682
		
683
		// remove from source list
684
		RemoveOne(list, item);
685
		
686
		// add to target list
687
		if (evenIfExists || toList.indexOf(item) === -1) {
688
			if (addToEnd) {
689
				toList.push(item);
690
			}else{
691
				toList.unshift(item);
692
			}
693
			return true;
694
		}
695
		
696
		return false;
697
	},
698
699
	
700
	contains: function(value){
701
		var list = this;
702
		if (list.length === 1) {
703
			return list[0] == value;
704
		}
705
		return list.indexOf(value) > -1;
706
	},
707
	containsAny: function(values){
708
		var list = this;
709
		return IndexOfAny(list, values) > -1;
710
	},
711
	containsAll: function(values){
712
		var list = this;
713
		
714
		// exit if either null
715
		if (list == null || values == null || list.length === 0 || values.length === 0) {
2 ignored issues
show
Best Practice introduced by
Comparing list to null using the == operator is not safe. Consider using === instead.
Loading history...
Best Practice introduced by
Comparing values to null using the == operator is not safe. Consider using === instead.
Loading history...
716
			return false;
717
		}
718
		
719
		// check if all found
720
		for (var f = 0, fl = values.length;f<fl;f++){
721
			if (list.indexOf(values[f]) === -1) {
722
				return false;
723
			}
724
		}
725
		return true;
726
	},
727
	
728
729
	indexOfArray: function(containsArr){
730
		var list = this;
731
		
732
		// returns index of containing list in main array
733
		
734
		if (list.length < containsArr.length) {
735
			return -1;
736
		}
737
		
738
		var cl = containsArr.length;
739
		for (var a = 0, al = list.length - (cl - 1);a<al;a++){
740
			
741
			var allMatch = true;
742
			for (var c = 0;c<cl;c++){
743
				if (list[a+c] != containsArr[c]) {
744
					allMatch = false;
745
					break;
746
				}
747
			}
748
			
749
			if (allMatch) {
750
				return a;
751
			}
752
		}
753
		return -1;
754
	},
755
756
	
757
	/** Returns the nearest existing slot value in the array. Returns `ifNoSlots` if the array is empty. */
758
	within: function(slot, ifNoSlots = null){
759
		var list = this;
760
		
761
		// return null if array empty
762
		var len = list.length;
763
		if (len === 0) {
764
			return ifNoSlots;
765
		}
766
		
767
		// return first slot if index negative
768
		if (slot < 0) {
769
			return list[0];
770
		}
771
		
772
		// return last slot if index more than last slot
773
		if (slot >= len) {
774
			return list[len - 1];
775
		}
776
		
777
		// return given slot if within array
778
		return list[slot];
779
	},
780
	
781
	first: function(list){
782
		var list = this;
783
		var len = list.length;
784
		if (len === 0) {
785
			return null;
786
		}
787
		return list[0];
788
	},
789
	firstExisting: function(slots, blankVal = null){
790
		var list = this;
791
		for (var s = 0, sl = slots.length;s<sl;s++){
792
			var val;
793
			if ((val = list[slots[s]]) != blankVal) {
794
				return val;
795
			}
796
		}
797
		return null;
798
	},
799
	last: function(list){
800
		var list = this;
801
		var len = list.length;
802
		if (len === 0) {
803
			return null;
804
		}
805
		return list[len-1];
806
	},
807
	lastX: function(count){
808
		var list = this;
809
		var s = (0).max(list.length - count);
810
		return list.slice(s, list.length);
811
	},
812
	setFirst: function(value){
813
		var list = this;
814
		var len = list.length;
815
		if (len === 0) {
816
			return;
817
		}
818
		list[0] = value;
819
	},
820
	setLast: function(value){
821
		var list = this;
822
		var len = list.length;
823
		if (len === 0) {
824
			return;
825
		}
826
		list[len-1] = value;
827
	},
828
	
829
	random: function(list){
830
		var list = this;
831
		
832
		// return null if array empty
833
		if (list.length === 0) {
834
			return null;
835
		}
836
		
837
		// return random slot within array
838
		return list[parseInt(Math.random() * 1000000) % list.length];
839
	},
840
841
	pick: function(IDs, sameSlots = false, fastAndUnsafe = false, out = null, evenIfNull = false){
842
		var list = this;
843
		if (out == null){
1 ignored issue
show
Best Practice introduced by
Comparing out to null using the == operator is not safe. Consider using === instead.
Loading history...
844
			out = [];
845
		}
846
		
847
		if (IDs){
848
			if (fastAndUnsafe) {
849
				
850
				for (var i = 0, il = IDs.length;i<il;i++){
851
					var id = IDs[i];
852
					var val = list[id];
853
					if (sameSlots) {
854
						out[id] = val;
855
					}else{
856
						out.push(val);
857
					}
858
				}
859
				
860
			}else{
861
				
862
				for (var i = 0, il = IDs.length;i<il;i++){
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable i already seems to be declared on line 850. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
Comprehensibility Naming Best Practice introduced by
The variable il already seems to be declared on line 850. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
863
					id = IDs[i];
864
					if (id > -1){
865
						val = list[id];
866
						if (val != null || evenIfNull) {
1 ignored issue
show
Best Practice introduced by
Comparing val to null using the != operator is not safe. Consider using !== instead.
Loading history...
867
							if (sameSlots) {
868
								out[id] = val;
869
							}else{
870
								out.push(val);
871
							}
872
						}
873
					}
874
				}
875
				
876
			}
877
		}
878
		
879
		return out;
880
	},
881
882
	/** Get the data of `list`, by searching `indexID` in `indexArr`, or return `defaultVal` if not found */
883
	getByMatchingArray: function(indexArr, indexID, defaultVal = null){
884
		var list = this;
885
		var slot = indexArr.indexOf(indexID);
886
		return slot === -1 ? defaultVal : list[slot];
887
	},
888
	/** Set the data of `list`, by searching `indexID` in `indexArr` */
889
	setByMatchingArray: function(indexArr, indexID, data){
890
		var list = this;
891
		var slot = indexArr.indexOf(indexID);
892
		if (slot === -1) {
893
			return false;
894
		}
895
		list[slot] = data;
896
		return true;
897
	},
898
	
899
	page: function(page, pageLength, invisibleRows = null){
900
		var list = this;
901
		
902
		// ensure page no. in limits
903
		var lastPage = Math.ceil(list.length / pageLength);
904
		page = page.limitTo(0, lastPage - 1);
905
		
906
		// get first/last row in page
907
		var pageStart = page*pageLength;/// 0-based - first row in page
908
		var pageEnd = (pageStart + pageLength) - 1;/// 0-based - last row in page
909
		
910
		// get on-page rows
911
		var visibleRows = list.getRange(pageStart, pageLength);
912
		
913
		// get off-page rows
914
		if (invisibleRows) {
915
			invisibleRows.addRange(list, 0, pageStart - 1);
916
			invisibleRows.addRange(list, pageEnd + 1, list.length - 1);
917
		}
918
		
919
		return visibleRows;
920
	},
921
	
922
	trim: function(returnNew = false, trimVal = null){
923
		var list = this;
924
		var first = IndexOf(list, trimVal, true);
925
		if (first === -1) {
926
			if (returnNew) {
927
				return [];
928
			}else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
929
				list.length = 0;
930
			}
931
		}else{
932
			var last = list.lastIndexOf(trimVal, true);
933
			if (returnNew) {
934
				return GetManySE(list, first, last);
935
			}else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
936
				
937
				if (first != -1 && first != 0){
1 ignored issue
show
Best Practice introduced by
Comparing first to 0 using the != operator is not safe. Consider using !== instead.
Loading history...
938
					DeleteManySE(list, 0, first-1);
939
				}
940
				if (last != -1){
941
					list.length = last - first + 1; 
942
				}
943
			}
944
		}
945
		return list;
946
	},
947
948
	trimLeft: function(returnNew = false, trimVal = null){
949
		var list = this;
950
		var first = IndexOf(list, trimVal, true);
951
		if (first === -1) {
952
			if (returnNew) {
953
				return [];
954
			}else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
955
				list.length = 0;
956
			}
957
		}else{
958
			if (returnNew) {
959
				return GetAfter(list, first);
960
			}else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
961
				if (first != -1 && first != 0){
1 ignored issue
show
Best Practice introduced by
Comparing first to 0 using the != operator is not safe. Consider using !== instead.
Loading history...
962
					DeleteManySE(list, 0, first-1);
963
				}
964
			}
965
		}
966
		return list;
967
	},
968
	trimRight: function(returnNew = false, trimVal = null){
969
		var list = this;
970
		var last = IndexOf(list, trimVal, true);
971
		if (last === -1) {
972
			if (returnNew) {
973
				return [];
974
			}else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
975
				list.length = 0;
976
			}
977
		}else{
978
			if (returnNew) {
979
				return GetBefore(list, last);
980
			}else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
981
				list.length = last + 1;
982
			}
983
		}
984
		return list;
985
	},
986
	
987 View Code Duplication
	transpose: function() {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
988
		var arr = this;
989
		var transposed = [];
990
		
991
		for (var r = 0; r < arr.length; r++) {
992
			for (var c = 0; c < arr[r].length; c++) {
993
				if (transposed[c] == null) {
1 ignored issue
show
Best Practice introduced by
Comparing transposed.c to null using the == operator is not safe. Consider using === instead.
Loading history...
994
					transposed[c] = [];
995
				}
996
				transposed[c][r] = arr[r][c];
997
			}
998
		}
999
		
1000
		return transposed;
1001
	},
1002
	
1003 View Code Duplication
	sort: function() {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1004
		var arr = this;
1005
		var transposed = [];
1006
		
1007
		for (var r = 0; r < arr.length; r++) {
1008
			for (var c = 0; c < arr[r].length; c++) {
1009
				if (transposed[c] == null) {
1 ignored issue
show
Best Practice introduced by
Comparing transposed.c to null using the == operator is not safe. Consider using === instead.
Loading history...
1010
					transposed[c] = [];
1011
				}
1012
				transposed[c][r] = arr[r][c];
1013
			}
1014
		}
1015
		
1016
		return transposed;
1017
	},
1018
	
1019
	none:null
1020
};
1021
1022
// register funcs
1023
UB.registerFuncs(Array.prototype, arrayFuncs);
1024